package fr.curriculumvitae.anthony.stephan.activities;

import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import fr.curriculumvitae.anthony.stephan.R;
import fr.curriculumvitae.anthony.stephan.backend.BackEnd;
import fr.curriculumvitae.anthony.stephan.backend.IPostMessageCallback;
import fr.curriculumvitae.anthony.stephan.objects.Message;
import fr.curriculumvitae.anthony.stephan.utils.JsonSerializer;
import fr.curriculumvitae.anthony.stephan.utils.Log;

public class ContactFormActivity extends Activity {
	
	private static final String PRIVATE_PREFS = "fr.curriculumvitae.anthony.stephan";
	private static final String PREF_MESSAGE = PRIVATE_PREFS+".Message";
	private static final String EMPTY = "";
	
	private static Context context;
	private static Toast mToast;
	private static ProgressDialog mDialog;
	
	private Message mMessage;
	private boolean messagePosted;
	
	private EditText etName;
	private EditText etFunction;
	private EditText etEnterprise;
	private EditText etEmail;
	private EditText etPhone;
	private EditText etMessage;
	private Button bActionSend;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// dismiss action bar
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		
        // set content view
		setContentView(R.layout.activity_contact_form);
		context = this;
		messagePosted = false;
		mDialog = new ProgressDialog(this);
		mMessage = new Message();
		
		// adapt width & height (with max limits if needed)
        final LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout_contact_form);
        ViewTreeObserver vto = layout.getViewTreeObserver(); 
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
            @SuppressWarnings("deprecation")
			@Override 
            public void onGlobalLayout() { 
            	layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                DisplayMetrics metrics = getResources().getDisplayMetrics();
                int activityFinalWidth = (int) (metrics.widthPixels * 0.90);
                int activityFinalHeight = (int) (metrics.heightPixels * 0.75);
                getWindow().setLayout(activityFinalWidth, activityFinalHeight);
            } 
        });
        
        fetchViews();
        customizeViews();
        setListeners();
	}
	
	
	private void fetchViews() {
		etName = (EditText) findViewById(R.id.editText_contact_form_name);
		etFunction = (EditText) findViewById(R.id.editText_contact_form_function);
		etEnterprise = (EditText) findViewById(R.id.editText_contact_form_enterprise);
		etEmail = (EditText) findViewById(R.id.editText_contact_form_mail);
		etPhone = (EditText) findViewById(R.id.editText_contact_form_phone);
		etMessage = (EditText) findViewById(R.id.editText_contact_form_message);
		bActionSend = (Button) findViewById(R.id.button_contact_form_action_send);
	}
	
	private void customizeViews() {
		// get last message if exists :
		SharedPreferences prefs = this.getSharedPreferences(PRIVATE_PREFS, Context.MODE_PRIVATE);
		String messageStr = prefs.getString(PREF_MESSAGE, null);
		if(messageStr != null) {
			mMessage = (Message) JsonSerializer.deserialize(messageStr, Message.class);
			if(mMessage != null) {
				etName.setText(mMessage.getName());
				etFunction.setText(mMessage.getFunction());
				etEnterprise.setText(mMessage.getEnterprise());
				etEmail.setText(mMessage.getEmail());
				etPhone.setText(mMessage.getPhone());
				etMessage.setText(mMessage.getMessage());
			} else {
				mMessage = new Message();
			}
		}
	}
	
	private void setListeners() {
		bActionSend.setOnClickListener(onSendClickListener);
		
		etName.setOnTouchListener(onEditTextTouchListener);
		etFunction.setOnTouchListener(onEditTextTouchListener);
		etEnterprise.setOnTouchListener(onEditTextTouchListener);
		etEmail.setOnTouchListener(onEditTextTouchListener);
		etPhone.setOnTouchListener(onEditTextTouchListener);
		etMessage.setOnTouchListener(onEditTextTouchListener);
		
		etName.addTextChangedListener(nameTextWatcher);
		etFunction.addTextChangedListener(functionTextWatcher);
		etEnterprise.addTextChangedListener(enterpriseTextWatcher);
		etEmail.addTextChangedListener(emailTextWatcher);
		etPhone.addTextChangedListener(phoneTextWatcher);
		etMessage.addTextChangedListener(messageTextWatcher);
	}
	
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		// dismiss dialog if needed :
		if(mDialog != null) {
			mDialog.dismiss();
		}
		// delete registered message if needed :
		SharedPreferences prefs = this.getSharedPreferences(PRIVATE_PREFS, Context.MODE_PRIVATE);
		Editor editor = prefs.edit().clear();
		// and add new message if not sent :
		if(!messagePosted) {
			editor.putString(PREF_MESSAGE, JsonSerializer.serialize(mMessage));
		}
		editor.commit();
	}
	
	
	private static boolean isValidEmail(String email) {
		Pattern p = Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$");
		Matcher m = p.matcher(email.toUpperCase(Locale.getDefault()));
		return m.matches();
	}
	
	
	  ///////////////
	 // LISTENERS //
	///////////////
	
	private OnClickListener onSendClickListener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			String name = etName.getEditableText().toString();
			String function = etFunction.getEditableText().toString();
			String enterprise = etEnterprise.getEditableText().toString();
			String email = etEmail.getEditableText().toString();
			String phone = etPhone.getEditableText().toString();
			String message = etMessage.getEditableText().toString();
			if(name == null || name.equals(EMPTY)) {
				etName.setHintTextColor(Color.RED);
				etName.setHint(R.string.contact_form_error_name);
				return;
			}
			if(function == null || function.equals(EMPTY)) {
				etFunction.setHintTextColor(Color.RED);
				etFunction.setHint(R.string.contact_form_error_function);
				return;
			}
			if(enterprise == null || enterprise.equals(EMPTY)) {
				etEnterprise.setHintTextColor(Color.RED);
				etEnterprise.setHint(R.string.contact_form_error_enterprise);
				return;
			}
			if((email == null || email.equals(EMPTY)) && (phone == null || phone.equals(EMPTY))) {
				etEmail.setHintTextColor(Color.RED);
				etEmail.setHint(R.string.contact_form_error_email);
				etPhone.setHintTextColor(Color.RED);
				etPhone.setHint(R.string.contact_form_error_phone);
				return;
			}
			if(!isValidEmail(email)) {
				etEmail.setText(EMPTY);
				etEmail.setHintTextColor(Color.RED);
				etEmail.setHint(R.string.contact_form_error_invalid_email);
				return;
			}
			if(message == null || message.equals(EMPTY)) {
				etMessage.setHintTextColor(Color.RED);
				etMessage.setHint(R.string.contact_form_error_message);
				return;
			}
			// close keyboard :
			InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			imm.hideSoftInputFromWindow(etName.getWindowToken(), 0);
			imm.hideSoftInputFromWindow(etFunction.getWindowToken(), 0);
			imm.hideSoftInputFromWindow(etEnterprise.getWindowToken(), 0);
			imm.hideSoftInputFromWindow(etEmail.getWindowToken(), 0);
			imm.hideSoftInputFromWindow(etPhone.getWindowToken(), 0);
			// open progress dialog :
			mDialog = ProgressDialog.show(context, 
					getResources().getString(R.string.contact_form_dialog_title), 
					getResources().getString(R.string.contact_form_dialog_message));
			// post message on server :
			mMessage = new Message(null, null, name, function, enterprise, email, phone, message, false);
			BackEnd.postMessage(mMessage, postCallback);
		}
	};
	
	
	private OnTouchListener onEditTextTouchListener = new OnTouchListener() {
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			if(v instanceof EditText) {
				EditText etv = (EditText) v;
				etv.setHintTextColor(Color.GRAY);
			}
			return false;
		}
	};
	
	
	  //////////////
	 // WATCHERS //
	//////////////
	
	private TextWatcher nameTextWatcher = new TextWatcher() {
		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {}
		@Override
		public void afterTextChanged(Editable s) {
			mMessage.setName(s.toString());
		}
	};
	
	private TextWatcher functionTextWatcher = new TextWatcher() {
		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {}
		@Override
		public void afterTextChanged(Editable s) {
			mMessage.setFunction(s.toString());
		}
	};
	
	private TextWatcher enterpriseTextWatcher = new TextWatcher() {
		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {}
		@Override
		public void afterTextChanged(Editable s) {
			mMessage.setEnterprise(s.toString());
		}
	};
	
	private TextWatcher emailTextWatcher = new TextWatcher() {
		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {}
		@Override
		public void afterTextChanged(Editable s) {
			mMessage.setEmail(s.toString());
		}
	};
	
	private TextWatcher phoneTextWatcher = new TextWatcher() {
		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {}
		@Override
		public void afterTextChanged(Editable s) {
			mMessage.setPhone(s.toString());
		}
	};
	
	private TextWatcher messageTextWatcher = new TextWatcher() {
		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {}
		@Override
		public void afterTextChanged(Editable s) {
			mMessage.setMessage(s.toString());
		}
	};
	
	
	  ///////////////
	 // CALLBACKS //
	///////////////
	
	private IPostMessageCallback postCallback = new IPostMessageCallback() {
		@Override
		public void postEnded(boolean success, String message) {
			if(mToast != null) {
				mToast.cancel();
			}
			if(mDialog != null) {
				mDialog.dismiss();
			}
			if(success) {
				mToast = Toast.makeText(context, R.string.contact_form_post_ok, Toast.LENGTH_LONG);
				mToast.show();
				messagePosted = true;
				finish();
			} else {
				mToast = Toast.makeText(context, R.string.contact_form_post_nok, Toast.LENGTH_LONG);
				mToast.show();
				if(mMessage != null) {
					Log.d("ContactFormActivity", "cant send, retry : "+mMessage);
					BackEnd.postMessage(mMessage);
				}
			}
		}
	};
	
}
